/**
 * 树形数据处理工具类
 * @author SPY
 * @description -- 对于树形数据进行必要的处理
 * @date  -- 2019/11/11
 */
import arrayUtils from './arrayUtils';

const treeUtils = {
  /**
   * 将树形list数据的叶子节点转化为一维数组
   * @param {object} treeList -- 要遍历的list对象,格式为:{id:1,name:'河南',subList:[{id:11,name:'郑州'}]},
   * @param {string} childListKey -- 树节点的子集list的id的名称
   */
  treeLeafToArray: (treeList = {}, childListKey = 'subList') => {
    const data: React.ReactText[] = [];
    const func = (treeList: any, childListKey: string) => {
      if (treeList[childListKey] && treeList[childListKey].length !== 0) {
        // 说明树节点有子节点
        treeList[childListKey].forEach((item: any) => {
          func(item, childListKey);
        });
      } else {
        // 说明树节点为叶子节点
        data.push(treeList);
      }
    };
    func(treeList, childListKey);
    return data;
  },

  /**
   * 将树形数据平铺为同级数组
   * @param {array} treeList -- 要平铺的list数组
   * @param {string} childListKey -- 树节点的子集list的id的名称
   */
  flatten: (treeList = [], childListKey = 'children') => {
    const data: React.ReactText[] = [];
    const func = (treeList: React.ReactText[], childListKey: string) => {
      treeList.forEach((item: any) => {
        data.push(item);
        if (item[childListKey] && item[childListKey].length !== 0) {
          //说明有子节点
          func(item[childListKey], (childListKey = 'children'));
        }
      });
    };
    func(treeList, childListKey);
    return data;
  },

  /**
   * 遍历树形数据函数(查找)
   * @param {array} treeList -- 要遍历的list数组
   * @param {string} childListKey -- 树节点的子集list的id的名称
   * @param {func} callback -- 回调函数,可以在函数做一些node节点id的数据处理
   * @param {object} parentNode -- 父级节点及子集的数据
   */
  forEach: (
    treeList: any = [],
    childListKey = 'subList',
    callback: (node: any) => void,
  ) => {
    if (!Array.isArray(treeList)) return;
    for (let i = 0; i < treeList.length; i++) {
      const node = treeList[i];
      callback(node); // 要查询的条件,以及查询之后的数据操作
      treeUtils.forEach(node[childListKey], childListKey, callback);
    }
  },
  // treeUtils.forEach(dataList, childListKey, (node, parentNode) => {
  //     if (value && searchMatcher(value, node, this.props)) {
  //         expandedKeys.push(node[idKey]);
  //     }
  // });

  /**
   * 组装树函数
   * @param {array} data -- 要组装的list数组
   * @param {string} idKey -- 树节点的id的名称
   * @param {string} parentKey -- 树节点的父节点id的名称
   * @param {string} childListKey -- 树节点的子集list的id的名称
   */
  toTree: (
    data = [],
    idKey = 'id',
    parentKey = 'pid',
    childListKey = 'subList',
  ) => {
    // 删除 所有 children,以防止多次调用
    data.forEach(function(item) {
      delete item[childListKey];
    });

    // 将数据存储为 以 id 为 KEY 的 map 索引数据列
    var map = {};
    data.forEach(function(item) {
      map[item[idKey]] = item;
    });
    var val: React.ReactText[] = [];
    data.forEach(item => {
      // 以当前遍历项，的pid,去map对象中找到索引的id
      var parent: any = map[item[parentKey]];
      // 如果找到索引，那么说明此项不在顶级当中,那么需要把此项添加到，他对应的父级中
      if (parent) {
        (parent[childListKey] || (parent[childListKey] = [])).push(item);
      } else {
        // 如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中，作为顶级
        val.push(item);
      }
    });
    return val;
  },
  // const data = [
  //     { id: 1, name: "办公管理", pid: 0 },
  //     { id: 2, name: "请假申请", pid: 1 },
  //     { id: 3, name: "出差申请", pid: 1 },
  //     { id: 4, name: "请假记录", pid: 2 },
  //     { id: 5, name: "系统设置", pid: 0 },
  //     { id: 6, name: "权限管理", pid: 5 },
  //     { id: 7, name: "用户角色", pid: 6 },
  //     { id: 8, name: "菜单设置", pid: 6 },
  // ];

  /**
   * 树结构排序函数
   * @param {array} data -- 要排序的树组
   * @param {string} sortField -- 根据排序的字段名称
   * @param {string} childListKey -- 树节点的子集list的id的名称
   * @param {string} orderBy -- 正序：'asc'  倒序：’desc‘
   */
  sortTree: (
    data: React.ReactText[] = [],
    sortField = 'id',
    childListKey = 'subList',
    orderBy = 'asc',
  ) => {
    // 默认正序
    const func = (
      data: React.ReactText[],
      sortField: string,
      childListKey: string,
      orderBy: string,
    ) => {
      if (!Array.isArray(data)) return;
      data
        .sort(arrayUtils.sortCallBack(sortField, orderBy))
        .forEach((node: any) => {
          func(node[childListKey], sortField, childListKey, orderBy);
        });
    };
    func(data, sortField, childListKey, orderBy);
    return data;
  },
};

export default treeUtils;
